﻿#region Header

/*
Behavioral Rating of Dancing Human Crowds based on Motion Patterns
By

Pascal Hauser 
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

and

Raphael Gfeller
Dipl. Ing. in Informatik, Hochschule für Technik Rapperswil, 2006
Master Thesis, Hochschule für Technik Rapperswil, 2008-2010

*/

#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Drawing;
using Emgu.CV;
using Emgu.CV.Structure;
using paravili.Services;
using Sebarf.Services.Interfaces;

#endregion

namespace paravili.Steps {
	/// <summary>
	/// Description of the class>
	/// </summary>
	public class FindClustersWithinImagesByBlockMatching :
		ProcessStepConverterWithMeasurement<Image<Lab, byte>, IList<IList<ColoredPoint>>> {
		#region Public Properties

		[ConfigurableNumericValue(Name = "Raster size", RangeFrom = 5, RangeTo = 100)]
		public int RasterSize { get; set; }

		[ConfigurabelBooleanValue(Name = "VisualizeGrid")]
		public bool VisualizeGrid { get; set; }

		[ConfigurabelStringValue(Name = "VisualizeClustersInImage")]
		public String VisualizeClustersInImage { get; set; }

		[ServiceRequest(IsOptional = true)]
		public IImageLocatorService ImageLocatorService { get; set; }

		#endregion

		#region Public Methods

		public FindClustersWithinImagesByBlockMatching() {
			RasterSize = 20;
			VisualizeClustersInImage = "BgrToLabConverter.ImageData";
			VisualizeGrid = true;
		}

		#endregion

		#region Private Methods

		protected override IList<IList<ColoredPoint>> Convert(Image<Lab, byte> toProcess) {
			if (toProcess == null) {
				return null;
			}
			Image<Lab, byte> cloneImg = toProcess.Copy();
			bool visualize = (VisualizeGrid && ImageLocatorService != null);
			Image<Lab, Byte> image = null;
			if (visualize) {
				image = ImageLocatorService.GetImage(VisualizeClustersInImage);
				visualize = image != null;
			}

			IList<IList<ColoredPoint>> toReturn = new List<IList<ColoredPoint>>();
			int squareSize = RasterSize;
			for (int col = 0; (col + 1) * (RasterSize) < cloneImg.Width; col++) {
				for (int row = 0; (row + 1) * (RasterSize) < cloneImg.Height; row++) {
					IList<ColoredPoint> toAdd = new List<ColoredPoint>();
					for (int colRaster = 0; colRaster < RasterSize; colRaster++) {
						for (int rowRaster = 0; rowRaster < RasterSize; rowRaster++) {
							int y = row * RasterSize + rowRaster;
							int x = col * RasterSize + colRaster;
							toAdd.Add(new ColoredPoint { Color = cloneImg[y, x], P = new Point(x, y) });
						}
					}
					toReturn.Add(toAdd);
					if (visualize) {
						image.Draw(new Rectangle(col * RasterSize, row * RasterSize, RasterSize, RasterSize), new Lab(1000, 1000, 1000),
									1);
					}
				}
			}

			StatisticValuesProviderService.SetStatisticValue("Clusters.Found", toReturn.Count);
			return toReturn;
		}

		#endregion
	}
}